package com.googlecode.entity_dao.core.entity;

import java.io.Serializable;
import java.util.UUID;

import javax.persistence.Column;
import javax.persistence.MappedSuperclass;

import org.apache.commons.lang.ObjectUtils;
import org.hibernate.annotations.NaturalId;

/**
 * Base class for entities that uses a syntetic oid
 * 
 * @param <ID> Java type of the primary key column.
 * 
 * @see MutablePersistentEntity
 * 
 * @author mauro.franceschini
 */
@MappedSuperclass
public abstract class OidBasedMutablePersistentEntity<ID extends Serializable> extends MutablePersistentEntity<ID> {
    private static final long serialVersionUID = 9049263542555247387L;

    protected static final int OID_COLUMN_LENGTH = 36;
    protected static final String OID_COLUMN_NAME = "OBJECT_ID";

    @NaturalId
    @Column(name = OID_COLUMN_NAME, length = OID_COLUMN_LENGTH, unique = true, updatable = false, nullable = false)
    private String oid;

    public OidBasedMutablePersistentEntity() {
        oid = generateOid();
    }

    public String getOid() {
        return oid;
    }

    protected void setOid(String oid) {
        this.oid = oid;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        result = prime * result + ObjectUtils.hashCode(oid);

        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof OidBasedMutablePersistentEntity))
            return false;

        @SuppressWarnings("unchecked")
        OidBasedMutablePersistentEntity<ID> other = (OidBasedMutablePersistentEntity<ID>) obj;

        return ObjectUtils.equals(oid, other.oid);
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        @SuppressWarnings("unchecked")
        OidBasedMutablePersistentEntity<ID> clone = (OidBasedMutablePersistentEntity<ID>) super.clone();
        clone.setOid(generateOid());
        return clone;
    }

    protected final String generateOid() {
        return UUID.randomUUID().toString();
    }
}
